package com.xbongbong.paas.help;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.AddProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.DetailTabEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.help.ProPermissionHelp;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @date 2022/02/11 16:00
 */
@Component
public class LinkListHelp {

    @Resource
    private WorkReportSetModel workReportSetModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private PaasFormModel paasFormModel;

    /**
     * 拼装关联列表的tab，获取最新的表单名称
     * @param linkList 关联列表
     * @param corpid 公司id
     */
    public void getLinkList(List<LinkListPojo> linkList, String corpid) throws XbbException {
        if (CollectionsUtil.isNotEmpty(linkList)) {
            Set<Long> appIdIn = new HashSet<>();
            Set<Long> menuIdIn = new HashSet<>();
            linkList.forEach(item->{
                appIdIn.add(item.getLinkAppId());
                if (Objects.nonNull(item.getLinkMenuId())) {
                    menuIdIn.add(item.getLinkMenuId());
                }
            });
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            param.put("idIn", appIdIn);
            List<PaasAppEntity> appList = paasAppModel.findEntitys(param);
            if (Objects.isNull(appList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Map<Long, PaasAppEntity> appMap = new HashMap<>(appList.size());
            appList.forEach(item->{
                appMap.put(item.getId(), item);
            });
            param.clear();
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            param.put("idIn", menuIdIn);
            List<PaasMenuEntity> menuList = paasMenuModel.findEntitys(param);
            if (Objects.isNull(menuList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Map<Long, PaasMenuEntity> menuMap = new HashMap<>(menuList.size());
            menuList.forEach(item->{
                menuMap.put(item.getId(), item);
            });
            Iterator<LinkListPojo> linkListIterator = linkList.iterator();
            Set<Long> idIn = new HashSet<>();
            Set<Long> workFormIdIn = new HashSet<>();
            while (linkListIterator.hasNext()) {
                LinkListPojo item = linkListIterator.next();
                if (Objects.equals(item.getEnable(), 0) || appMap.isEmpty() || menuMap.isEmpty()) {
                    linkListIterator.remove();
                    continue;
                }
                // 开启了应用和菜单才需要显示
                if (appMap.containsKey(item.getLinkAppId()) && menuMap.containsKey(item.getLinkMenuId())) {
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                        workFormIdIn.add(item.getLinkFormId());
                    } else {
                        idIn.add(item.getLinkFormId());
                    }
                }
            }
            if (!workFormIdIn.isEmpty()) {
                param.clear();
                param.put("corpid", corpid);
                param.put("del", DelEnum.NORMAL.getDel());
                param.put("idIn", workFormIdIn);
                param.put("enable", 1);
                List<WorkOrderFormEntity> formList = workOrderFormModel.findEntitys(param);
                if (Objects.isNull(formList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
                Map<Long, WorkOrderFormEntity> formMap = new HashMap<>(formList.size());
                formList.forEach(item->{
                    formMap.put(item.getId(), item);
                });
                Iterator<LinkListPojo> iterator = linkList.iterator();
                while (iterator.hasNext()) {
                    LinkListPojo item= iterator.next();
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                        DetailTabPojo detailTabPojo = new DetailTabPojo();
                        BeanUtil.copyProperties(item, detailTabPojo);
                        WorkOrderFormEntity workOrderFormEntity = formMap.get(item.getLinkFormId());
                        if (Objects.isNull(workOrderFormEntity)) {
                            iterator.remove();
                            continue;
                        }
                        item.setName(workOrderFormEntity.getName());
                    }

                }
            }
            if (!idIn.isEmpty()) {
                param.clear();
                param.put("corpid", corpid);
                param.put("del", DelEnum.NORMAL.getDel());
                param.put("enable", 1);
                param.put("idIn", idIn);
                List<PaasFormEntityExt> formList = paasFormModel.list(param);
                if (Objects.isNull(formList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
                Map<Long, PaasFormEntityExt> formMap = new HashMap<>(formList.size());
                formList.forEach(item->{
                    formMap.put(item.getId(), item);
                });
                Iterator<LinkListPojo> iterator = linkList.iterator();
                while (iterator.hasNext()) {
                    LinkListPojo item= iterator.next();
                    if (!Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                        DetailTabPojo detailTabPojo = new DetailTabPojo();
                        BeanUtil.copyProperties(item, detailTabPojo);
                        PaasFormEntityExt paasFormEntityExt = formMap.get(item.getLinkFormId());
                        if (Objects.isNull(paasFormEntityExt)) {
                            iterator.remove();
                            continue;
                        }
                        item.setName(paasFormEntityExt.getName());
                    }
                }
            }
        }
    }

    /**
     * 获取关联列表的tab
     * @param linkList 关联列表
     * @param detailTabList 已有的tab
     * @param userVO 用户信息
     */
    public void getLinkListTab(List<LinkListPojo> linkList, List<DetailTabPojo> detailTabList, UserVO userVO) {
        if (CollectionsUtil.isEmpty(linkList)){
            return;
        }
        Iterator<LinkListPojo> iterator = linkList.iterator();
        Set<Long> workFormSet = new HashSet<>();
        while (iterator.hasNext()) {
            LinkListPojo item= iterator.next();
            if (Objects.equals(item.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                Integer businessType = item.getLinkBusinessType();
                if (!userVO.isAdminOrBoss() && Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) && !userVO.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_VIEW.getAlias())) {
                    iterator.remove();
                    continue;
                } else if (!userVO.isAdminOrBoss() && Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType) && !userVO.getPermSet().contains(ProPermissionAliasEnum.OPPORTUNITY_VIEW.getAlias())) {
                    iterator.remove();
                    continue;
                } else if (Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), businessType)
                        || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), businessType)
                        ||Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), businessType) ) {
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(userVO, userEntity);
                    WorkReportSetVisibleRange workReportSetVisibleRange = workReportSetModel.getVisibleRange(userEntity);
                    if (!workReportSetVisibleRange.getDayEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), businessType)) {
                        iterator.remove();
                        continue;
                    } else if (!workReportSetVisibleRange.getMonthEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), businessType)) {
                        iterator.remove();
                        continue;
                    } else if (!workReportSetVisibleRange.getWeekEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), businessType)) {
                        iterator.remove();
                        continue;
                    }
                    if (ExplainUtil.isWorkReport(businessType)) {
                        item.setLinkBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                        item.setLinkSubBusinessType(businessType);
                    }

                } else {
                    XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                    if (!userVO.isAdminOrBoss() && !userVO.getPermSet().contains(xbbRefTypeEnum.getAlias())) {
                        iterator.remove();
                        continue;
                    }
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), businessType)) {
                        // 工单权限判断
                        if (workFormSet.isEmpty()) {
                            List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.getTemplateWithPermission(userVO.getCorpid(), userVO, item.getLinkAppId(), null);
                            workOrderFormList.forEach(workOrderFormEntity->{
                                workFormSet.add(workOrderFormEntity.getId());
                            });
                        }
                        if (!workFormSet.contains(item.getLinkFormId())) {
                            // 无工单使用权限
                            iterator.remove();
                            continue;
                        }
                    }
                }
            } else {
                Set<Long> idSet = ProPermissionHelp.getPaasViewMenuIdSet(userVO.getPaasPermissions());
                if (!userVO.isAdminOrBoss() && !idSet.contains(item.getLinkMenuId())) {
                    iterator.remove();
                    continue;
                }
            }
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(item, detailTabPojo);
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                detailTabPojo.setAttr(item.getLinkBusinessType() + StringConstant.UNDER_LINE +item.getLinkFormId().toString() + StringConstant.UNDER_LINE + item.getAttr());
            } else {
                detailTabPojo.setAttr(item.getLinkFormId().toString() + StringConstant.UNDER_LINE + item.getAttr());
            }
            detailTabPojo.setKey(DetailTabEnum.LINK_LIST.getKey());
            detailTabPojo.setName(item.getName());

            detailTabPojo.setLinkList(item);
            detailTabList.add(detailTabPojo);

        }
    }

    /**
     * 获取关联列表的操作按钮
     * @param linkList 关联列表
     * @param workFlowList 操作按钮
     * @param userVO 用户
     */
    public List<WorkFlowPojo> getLinkListAddButton(List<LinkListPojo> linkList, UserVO userVO, PlatFormEnum platForm) {
        List<WorkFlowPojo> workFlowList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(linkList)){
            return workFlowList;
        }
        Set<Long> workFormSet = new HashSet<>();
        Iterator<LinkListPojo> iterator = linkList.iterator();
        while (iterator.hasNext()) {
            LinkListPojo item= iterator.next();
            Integer linkBusinessType = item.getLinkBusinessType();
            if (Objects.equals(platForm, PlatFormEnum.DINGTALK) && Objects.equals(linkBusinessType, XbbRefTypeEnum.PRODUCT.getCode())) {
                // 移动端不需要新建产品
                continue;
            }
            if (Objects.equals(item.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                if (Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), linkBusinessType)
                        || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), linkBusinessType)
                        ||Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), linkBusinessType) ) {
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(userVO, userEntity);
                    WorkReportSetVisibleRange workReportSetVisibleRange = workReportSetModel.getVisibleRange(userEntity);
                    if (!workReportSetVisibleRange.getDayEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), linkBusinessType)) {
                        iterator.remove();
                        continue;
                    } else if (!workReportSetVisibleRange.getMonthEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), linkBusinessType)) {
                        iterator.remove();
                        continue;
                    } else if (!workReportSetVisibleRange.getWeekEnable() && Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), linkBusinessType)) {
                        iterator.remove();
                        continue;
                    }
                    if (ExplainUtil.isWorkReport(linkBusinessType)) {
                        item.setLinkBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                        item.setLinkSubBusinessType(linkBusinessType);
                    }
                } else {
                    AddProPermissionAliasEnum addProPermissionAliasEnum = AddProPermissionAliasEnum.getByCode(item.getLinkBusinessType());
                    if (Objects.isNull(addProPermissionAliasEnum)) {
                        continue;
                    }
                    if (!userVO.isAdminOrBoss() && !userVO.getPermSet().contains(addProPermissionAliasEnum.getAlias())) {
                        iterator.remove();
                        continue;
                    }
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkBusinessType)) {
                        // 工单权限判断
                        if (workFormSet.isEmpty()) {
                            List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.getTemplateWithPermission(userVO.getCorpid(), userVO, item.getLinkAppId(), null);
                            workOrderFormList.forEach(workOrderFormEntity->{
                                workFormSet.add(workOrderFormEntity.getId());
                            });
                        }
                        if (!workFormSet.contains(item.getLinkFormId())) {
                            // 无工单使用权限
                            iterator.remove();
                            continue;
                        }
                    }
                }

            } else {
                Set<Long> idSet = ProPermissionHelp.getPaasCreateMenuIdSet(userVO.getPaasPermissions());
                if (!userVO.isAdminOrBoss() && !idSet.contains(item.getLinkMenuId())) {
                    iterator.remove();
                    continue;
                }
            }
            WorkFlowPojo workFlowPojo = new WorkFlowPojo();
            workFlowPojo.setId(item.getAttr() + "_" + item.getLinkFormId());
            workFlowPojo.setAttr(DetailTabEnum.LINK_LIST.getKey());
            workFlowPojo.setBtnType(SaasButtonEnum.ADD.getAttr());
            workFlowPojo.setBusinessType(item.getLinkBusinessType());
            workFlowPojo.setValue(I18nMessageUtil.getMessage(I18nStringConstant.NEW_ADD) + item.getName());
            workFlowPojo.setLinkList(item);
            workFlowList.add(workFlowPojo);
        }
        return workFlowList;
    }

    /**
     * 设置手机端的关联列表的按钮
     * @param topPermissions
     * @param linkList
     * @param loginUser
     * @return void
     * @author 吴峰
     * @date 2020/10/13 16:15
     * @throws XbbException
     */
    public List<TopPermissionsPoJo> setMobileLinkListButton( List<LinkListPojo> linkList, UserVO loginUser) {
        List<TopPermissionsPoJo> topPermissions = new ArrayList<>();
        if ( CollectionsUtil.isNotEmpty(linkList) ) {
            topPermissions = topPermissions == null ? new ArrayList<>() : topPermissions;
            for ( LinkListPojo item : linkList ) {
                if ( Objects.equals(item.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode()) ) {
                    Integer linkBusinessType = item.getLinkBusinessType();
                    if ( Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), linkBusinessType)
                            || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), linkBusinessType)
                            || Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), linkBusinessType) ) {
                        UserEntity userEntity = new UserEntity();
                        BeanUtil.copyProperties(loginUser, userEntity);
                        WorkReportSetVisibleRange workReportSetVisibleRange = workReportSetModel.getVisibleRange(userEntity);
                        if (ExplainUtil.isWorkReport(linkBusinessType)) {
                            item.setLinkBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                            item.setLinkSubBusinessType(linkBusinessType);
                        }
                        if ( workReportSetVisibleRange.getDayEnable()
                                || workReportSetVisibleRange.getMonthEnable()
                                || workReportSetVisibleRange.getWeekEnable() ) {
                            topPermissions.add(getPermission(item));
                        }
                    } else {
                        AddProPermissionAliasEnum addProPermissionAliasEnum = AddProPermissionAliasEnum.getByCode(linkBusinessType);
                        if (Objects.nonNull(addProPermissionAliasEnum) && (loginUser.getPermSet().contains(addProPermissionAliasEnum.getAlias())
                                || loginUser.isAdminOrBoss())) {
                            topPermissions.add(getPermission(item));
                        }
                    }

                } else {
                    Set<Long> idSet = ProPermissionHelp.getPaasCreateMenuIdSet(loginUser.getPaasPermissions());
                    // 上部按钮权限
                    Boolean isAdmin = loginUser.isAdminOrBoss();
                    if ( idSet.contains(item.getLinkMenuId()) || isAdmin ) {
                        topPermissions.add(getPermission(item));
                    }
                }
            }
        }
        return topPermissions;
    }


    private static TopPermissionsPoJo getPermission(LinkListPojo item) {
        TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
        // 为了前端保证attr唯一，而用表单id，web端使用的是DetailTabEnum.LINK_LIST.getKey()
        topPermissionsPoJo.setAttr(item.getAttr() + "_" + item.getLinkFormId().toString());
        topPermissionsPoJo.setValue(SaasButtonEnum.ADD.getValue() + item.getName());
        topPermissionsPoJo.setBusinessType(item.getLinkBusinessType());
        topPermissionsPoJo.setBtnType(SaasButtonEnum.ADD.getAttr());
        topPermissionsPoJo.setLinkList(item);
        return topPermissionsPoJo;
    }


}
